﻿#include <io.h>
#include <fstream>
#include "Book.h"
#include "Prompt.h"
#include "Menu.h"
#include "json.hpp"
using namespace nlohmann;

list<Book> Book::BookList = list<Book>();

/**
 * @brief 创建一个书的对象，自动加入BookList
 */
Book::Book(string ISDN, string name) : ISDN(ISDN), name(name)
{
	this->id = getNextBookId();
};
/**
 * @brief 创建一个书的对象，自动加入BookList
 */
Book::Book(int id, string ISDN, string name) : id(id), ISDN(ISDN), name(name) {};
/**
 * @brief 重载输入
 */
istream& operator>>(istream& input, Book& b)
{
	input >> b.ISDN >> b.name;
	return input;
}
/**
 * @brief 重载输出
 */
ostream& operator<<(ostream& output, const Book& b)
{
	output << "ISDN：" << b.ISDN << "书名：" << b.name;
	return output;
}
/**
 * @brief 比较两个图书对象的ISDN是否相等
 */
bool operator==(const Book& a, const Book& b)
{
	return a.id == b.id;
}
/**
 * @brief 获取下一个Book记录的id值
 *
 * @return int
 */
int Book::getNextBookId()
{
	int max_id = 0;
	for (auto iter = BookList.begin(); iter != BookList.end(); iter++)
	{
		if (iter->id > max_id)
			max_id = iter->id;
	}
	return max_id + 1;
}
/**
 * @brief
 *
 * @return string
 */
string Book::toJson()
{
	string json_str("[");
	for (auto iter = BookList.begin(); iter != BookList.end(); iter++)
	{
		json json_item = { {"id", iter->id}, {"ISDN", iter->ISDN}, {"name", iter->name} };
		json_str.append(json_item.dump());
	}
	json_str.append("]");
	return json_str;
}

/**
 * @brief json 字符串转数组
 *
 * @return string
 */
list<Book> Book::fromJson(string json_str)
{
	json json_array = json::parse(json_str);
	list<Book> Book_list;
	for (auto iter = json_array.begin(); iter != json_array.end(); iter++)
	{
		Book r = Book((*iter)["id"], (*iter)["ISDN"], (*iter)["name"]);
		Book_list.push_back(r);
	}
	return Book_list;
}

/**
 * @brief 根据图书id查图书
 *
 * @return Book*
 */
Book* Book::queryById(int Book_id)
{
	for (auto r = BookList.begin(); r != BookList.end(); r++)
	{
		if (r->id == Book_id)
			return &*r;
	}
	return nullptr;
}
/**
 * @brief 根据图书名查图书
 *
 * @return Book*
 */
Book* Book::queryByName(string Book_name)
{
	for (auto r = BookList.begin(); r != BookList.end(); r++)
	{
		if (r->name == Book_name)
			return &*r;
	}
	return nullptr;
}
/**
 * @brief 根据图书ISDN查图书
 *
 * @return Book*
 */
Book* Book::queryByISDN(string isdn)
{
	for (auto r = BookList.begin(); r != BookList.end(); r++)
	{
		if (r->ISDN == isdn)
			return &*r;
	}
	return nullptr;
}

/**
 * @brief 根据id记录删除读者
 *
 * @param Book_id
 * @return int 1 表示不存在删除失败，0表示删除成功
 */
int Book::delById(int Book_id)
{
	Book* r = queryById(Book_id);
	if (r != nullptr)
	{
		BookList.remove(*r);
		return 0;
	}
	else
	{
		return 1;
	}
}

/**
 * @brief 添加读者
 *
 */
void Book::addBook()
{
	string id_string;
	int id = -1;
	string isdn, book_name;
	isdn = prompt("请输入ISDN：");
	book_name = prompt("请输入书名：");
	Book b(isdn, book_name);
	BookList.push_back(b);
	cout << "图书添加成功" << endl;
	saveFile();
}

/**
 * @brief 输出读者列表
 *
 */
void Book::listBook()
{
	cout << toJson() << endl;
}

void Book::delBook()
{
	Menu menu("请选择删除依据", { "id", "name", "ISDN" });
	Menu::MenuSelection del_option = menu.show();
	Book* book_to_del = nullptr;
	if (del_option == 1)
	{
		// 按照id删除
		int id;
		string id_string = prompt("请输入要删除的图书id：");
		id = atoi(id_string.c_str());
		book_to_del = queryById(id);
	}
	else if (del_option == 2)
	{
		// 按照姓名删除第一个匹配
		string name_string = prompt("请输入要删除的图书名：");
		book_to_del = queryByName(name_string);
	}
	else if (del_option == 3)
	{
		// 按照ISDN删除
		string isdn_string = prompt("请输入要删除的图书ISDN：");
		book_to_del = queryByISDN(isdn_string);
	}
	// 判断是否查找到读者
	if (book_to_del != nullptr)
	{
		cout << "成功删除读者：id=" << book_to_del->id << " name=" << book_to_del->name << endl;
		delById(book_to_del->id);
	}
	else
	{
		cout << "图书不存在！";
	}
	saveFile();
}

const char* Book::file_name = "data/books.txt";

/**
 * @brief 将读者列表写入文件
 *
 */
void Book::saveFile()
{
	ofstream outfile;
	outfile.open(file_name, ios::out);
	outfile << toJson() << endl;
	outfile.close();
}
/**
 * @brief 从文件加载数据
 *
 */
void Book::loadFromFile()
{
	cout << "加载图书记录" << endl;
	if (_access(file_name, 0) == 0)
	{
		ifstream infile;
		string json_str;
		infile.open(file_name, ios::out);
		infile >> json_str;
		infile.close();
		BookList = fromJson(json_str);
		cout << "加载了" << BookList.size() << "条图书记录";
	}
	else
	{
		cout << "没有图书列表文件" << endl;
	}
}
